package org.bing.zion.filter.comsat;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Map;

import org.bing.zion.core.ProtocolFilterAdapter;
import org.bing.zion.core.ProtocolFilterChain;
import org.bing.zion.core.Session;


public class ComsatProtocolFilter extends ProtocolFilterAdapter {
	private static final String SESSION_KEY_CURRFRAG = "KEY.FILTER.COMSAT.CURRFRAG";
	private static final int ITEM_MAX_SIZE = 256 * 1024;
	private ComsatEncoder encoder = new ComsatEncoder();
	private ComsatDecoder decoder = new ComsatDecoder();

	/**
	 * Format {item:MD-MA-INVOCATION,host:127.0.0.1,date:2010-09-09 12:23:32,name:login.html,count:123,period:2345}
	 */

	@Override
	public void messageReceived(ProtocolFilterChain chain, Session session, Object msg) throws IOException {
		if (msg instanceof ByteBuffer) {
			ByteBuffer buf = (ByteBuffer) msg;
			ByteArrayOutputStream frag = (ByteArrayOutputStream) session.getAttribute(SESSION_KEY_CURRFRAG);
			if (frag == null) {
				frag = new ByteArrayOutputStream(1024);
				session.setAttribute(SESSION_KEY_CURRFRAG, frag);
			}
			frag.write(buf.array(), 0, buf.position());
			Object obj = decoder.decode(frag);
			while (obj != null) {
				super.messageReceived(chain, session, msg);
				obj = decoder.decode(frag);
			}
			// error format control, max size manage
			if (frag.size() > ITEM_MAX_SIZE) {
				session.removeAttribute(SESSION_KEY_CURRFRAG);
				throw new RuntimeException("Error format or object's size over 256K! ");
			}
		} else {
			super.messageReceived(chain, session, msg);
		}
	}

	@Override
	public void messageSent(ProtocolFilterChain chain, Session session, Object msg) throws IOException {
		if (msg instanceof String || msg instanceof Map) {
			session.flush(ByteBuffer.wrap(encoder.encode(msg)));
		} else {
			super.messageSent(chain, session, msg);
		}
	}

}
